﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ManagedWinapi;
using ManagedWinapi.Windows;

namespace wutils
{
    public partial class wutils : Form
    {
        private static readonly bool debug = false;

        private static string debugText;

        private static Configuration config = Configuration.LoadConfiguration();
        private static TaskStrip strip;
        private static TaskMan taskMan = new TaskMan();

        public wutils()
        {
            InitializeComponent();
            Initialize();
        }

        #region Initializers

        private void Initialize()
        {
            InitializeHotkeys();

            WindowUtils.MinimizedWindowsChanged += OnMinimizedWindowsChanged;
            WindowUtils.OnTopWindowsChanged += OnOnTopWindowsChanged;

            SetupStrip();
        }
        private void InitializeHotkeys()
        {
            config.ToTray.HotkeyPressed += SendToTrayHotkeyPressed;
            config.OnTop.HotkeyPressed += OnTopHotkeyPressed;
            config.TaskMan.HotkeyPressed += TaskManHotkeyPressed;
            config.RestoreAll.HotkeyPressed += RestoreAllHotkeyPressed;
            config.ToggleTaskStrip.HotkeyPressed += ToggleTaskStripHotkeyPressed;
            config.Exit.HotkeyPressed += onExitHotkey;
            config.EnableConfiguration();
        }

        #endregion

        #region Debug Helpers

        private static void DebugLog(SystemWindow window)
        {
            if (!debug) return;

            string flags = "";
            foreach (string s in window.ExtendedStyle.ToString().Split(','))
            {
                flags += "WindowExStyleFlags." + s.Trim() + " | ";
            }
            flags = flags.Substring(0, flags.Length - 3);

            debugText += string.Format("\r\nClassName = \"{0}\",\r\n"
                                            + "Title = \"{1}\",\r\n" +
                                            "Flags = {2}\r\n", window.ClassName, window.Title, flags);
        }

        #endregion

        #region Important Stuff

        private static void SendToTray()
        {
            SystemWindow window = SystemWindow.ForegroundWindow;
            DebugLog(window);

            try
            {
                WindowUtils.SendToTray(window);
            }
            catch (DisallowedWindowException e) { }
        }
        private static void ToggleOnTop()
        {
            SystemWindow window = SystemWindow.ForegroundWindow;
            DebugLog(window);
            try
            {
                WindowUtils.ToggleOnTop(window);
            }
            catch (DisallowedWindowException e) { }
        }
        private static void ResetAll()
        {
            WindowUtils.ResetAll();
        }

        private void SetConfig()
        {
            config.DisableConfiguration();

            config.ToTrayKey = ToTrayBox.KeyCode;
            config.OnTopKey = OnTopBox.KeyCode;
            config.TaskManKey = TaskManBox.KeyCode;
            config.RestoreAllKey = RestoreAllBox.KeyCode;
            config.TaskStripKey = TaskStripBox.KeyCode;
            config.ExitKey = ExitBox.KeyCode;

            config.ShowTaskStrip = TaskStripChk.Checked;
            SetupStrip();

            config.EnableConfiguration();

            config.SaveConfiguration();
        }
        private void LoadConfig()
        {
            ToTrayBox.KeyCode = config.ToTrayKey;
            OnTopBox.KeyCode = config.OnTopKey;
            TaskManBox.KeyCode = config.TaskManKey;
            RestoreAllBox.KeyCode = config.RestoreAllKey;
            TaskStripBox.KeyCode = config.TaskStripKey;
            ExitBox.KeyCode = config.ExitKey;

            TaskStripChk.Checked = config.ShowTaskStrip;
        }

        private static void SetupStrip()
        {
            if (config.ShowTaskStrip && strip == null)
            {
                strip = new TaskStrip();
                strip.ResizeEnd += strip_ResizeEnd;
                strip.Size = config.StripSize;
                strip.Location = config.StripLocation;
                strip.Rebuild();
                strip.Show();
            }
            else if (!config.ShowTaskStrip && strip != null)
            {
                strip.Hide();
                strip.ResizeEnd -= strip_ResizeEnd;
                strip.Destroy();
                strip = null;
            }
        }

        private void RebuildMenu()
        {
            var items = wutilsMenu.Items.OfType<MinimizedWindowMenuItem>();
            foreach (var item in items)
            {
                wutilsMenu.Items.Remove(item);
            }
            var windows = new List<SystemWindow>(WindowUtils.MinimizedWindows);
            foreach (var window in windows)
            {
                wutilsMenu.Items.Insert(0, new MinimizedWindowMenuItem(window));
            }
        }

        #endregion

        #region GUI

        private void ShowHelpBalloon()
        {
            //wutilsIcon.ShowBalloonTip(1000, "Help",
            //                          string.Format("Use Win+{0} for \"Always on top\"\n", toTrayHotkey.KeyCode) +
            //                          string.Format("Use Win+{0} for \"Send to tray\"\n", onTopHotkey.KeyCode) +
            //                          string.Format("Use Win+{0} to exit ToTray App", exitHotkey.KeyCode),
            //                          ToolTipIcon.Info);
        }
        private void ShowOnTopInfoBalloon(SystemWindow window)
        {
            string text = String.Format("\"{0}\"", window.Title);

            text += window.TopMost ? " set to always on top." : " returned to normal behavior.";

            wutilsIcon.ShowBalloonTip(500, "Info!", text, ToolTipIcon.Info);
        }

        #endregion

        #region Handlers

        private void wutilsIcon_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (wutilsMenu.Items.OfType<MinimizedWindowMenuItem>().Count() != WindowUtils.MinimizedWindows.Count())
                    RebuildMenu();
                return;
            }
            LoadConfig();
            Show();
        }
        private void OnOnTopWindowsChanged(object sender, WindowEventArgs e)
        {
            var window = e.Window;
            ShowOnTopInfoBalloon(window);
        }
        private void OnMinimizedWindowsChanged(object sender, WindowEventArgs e)
        {
            if (e.Action != EventAction.ADDED) return;

            wutilsMenu.Items.Insert(0, new MinimizedWindowMenuItem(e.Window));
        }
        private void ShortcutChanged(object sender, EventArgs e)
        {
            ShortcutBox sb = (ShortcutBox)sender;
            sb.WindowsKey = true;
            sb.Ctrl = false;
            sb.Alt = false;
            sb.Shift = false;
        }
        static void strip_ResizeEnd(object sender, EventArgs e)
        {
            TaskStrip s = (TaskStrip)sender;
            config.StripLocation = new Point(s.Location.X, s.Location.Y);
            config.StripSize = new Size(s.Size.Width, s.Size.Height);
        }

        private static void SendToTrayHotkeyPressed(object sender, EventArgs e)
        {
            SendToTray();
        }
        private static void OnTopHotkeyPressed(object sender, EventArgs e)
        {
            ToggleOnTop();
        }
        private static void TaskManHotkeyPressed(object sender, EventArgs e)
        {
            if (WindowUtils.MinimizedWindows.Count() == 0) return;

            if (taskMan.Visible)
            {
                taskMan.FocusNext();
                //taskMan.Hide();
            }
            else
            {
                taskMan.Show();
            }
        }
        private static void RestoreAllHotkeyPressed(object sender, EventArgs e)
        {
            ResetAll();
        }
        private static void ToggleTaskStripHotkeyPressed(object sender, EventArgs e)
        {
            config.ShowTaskStrip = !config.ShowTaskStrip;
            SetupStrip();
        }

        private void OKBtn_Click(object sender, EventArgs e)
        {
            try
            {
                SetConfig();
                Hide();
            }
            catch (HotkeyAlreadyInUseException ex)
            {
                MessageBox.Show(this, ex.Data["message"].ToString(), "Key In Use!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void CancelBtn_Click(object sender, EventArgs e)
        {
            Hide();
        }
        private void LoadDefaultBtn_Click(object sender, EventArgs e)
        {
            config = Configuration.LoadDefaultConfiguration();
            LoadConfig();
        }

        #endregion

        #region Exits

        private void onExitHotkey(object sender, EventArgs e)
        {
            Exit();
        }
        private void ExitHandler(object sender, EventArgs e)
        {
            Exit();
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Exit();
        }
        private void Exit()
        {
            config.SaveConfiguration();

            WindowUtils.MinimizedWindowsChanged -= OnMinimizedWindowsChanged;
            WindowUtils.OnTopWindowsChanged -= OnOnTopWindowsChanged;

            WindowUtils.ResetAll();

            wutilsIcon.Visible = false;
            Application.Exit();
        }

        #endregion

    }
}